<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>UI Customizaton Prototype</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="prototype.js" type="text/javascript"></script>
<script src="behaviour.js" type="text/javascript"></script>
<!--  script src="scriptaculous.js" type="text/javascript"></script -->
<script src="dojo/dojo-0.2.2-kitchen_sink/dojo.js" type="text/javascript"></script>
<script type="text/javascript">
    dojo.require("dojo.event.*");       // sophisticated AOP event handling
    dojo.require("dojo.dnd.*");         // drag-and-drop
    dojo.require("dojo.fx.*");          // animations and eye candy
    dojo.require("dojo.widget.Editor"); // stable, portable HTML WYSIWYG
</script>
<!-- link rel="stylesheet" href="../test.css" type="text/css" / -->

<style type="text/css" media="screen">
	body {
		font-family: sans-serif;
		font-size: 10pt;
		margin: 0 0 0 0;
	}
	
	.container {
		display: block;
		margin: 0 0 0 0;
		padding: 0 0 0 0;
	}
	
	.customizer-button {
		background-color: #ECF3E1;
		border:1px solid #C5DEA1;
		cursor: pointer;
		/*margin: 0px 4px 0px 4px;*/
	}
	.customizer-button:hover {
		background-color: yellow;
	}

	#root {
		display: block;
	}
	
	#customizer {
	}
	
	#glasspane {
		display: block;
		position: absolute;
		top: 0px;
		left: 0px;
		width: 100%;
		height: 100%;
		z-index: 1000;
		background-color: transparent;
		/*background-color: rgb(170,197,192); opacity: .1;*/
	}
	
	#glasspane-highlighter {
		position: absolute;
		top: 0px;
		left: 0px;
		width: 0px;
		height: 0px;
		border:1px dotted  red;
	}

	#glasspane-inline-editor {
		position: absolute;
		top: 0px;
		left: 0px;
		width: 0px;
		height: 0px;
		background-color: white;
		border:1px solid black;
		overflow: auto; 
	}
	
	#glasspane-actual-editor {
	}

	div.handle {
		position: absolute;
		width: 5px;
		height: 5px;
		background-color: red;
	}
	
	#customizer-toolbar {
		border:1px solid #C5DEA1;
	}
	
	#customizer-label {
		font-weight: bold;
	}

	#customize-button {
		float: right;
	}
	
	/*-----------------------------------------------------------------------------------*/
	/* Container template styles */
	.container span.tab {
		background-color: rgb(170,197,192);
		color: white;
		font-weight: bold;
		border:1px solid #C5DEA1;
		cursor: pointer;
		padding: 0px 4px;
	}

	.container span.tab:hover {
		color: yellow;
	}
	
	/* Marker only - should contain no physical style */
	.component { }
	
	.titlebar {
		background-color: rgb(170,197,192);
		font-weight: bold;
		color: white;
		padding: 0px 4px 0px 4px;
	}

	.menu-button {
		color: black;
		font-weight: normal;
		background-color: #ECF3E1;
		border-bottom: 1px solid #C5DEA1;
		cursor: pointer;
		padding: 0px 4px 0px 4px;
	}
	.menu-button:hover {
		background-color: yellow;
	}

	#container1 {
	}

	#container2 {
		clear: both;
		margin-left: 5px;
	}

	#tab-submenu {
		clear: both;
		background-color: rgb(170,197,192);
	}
	
	#container3 {
		clear: both;
		float: left;
		margin-left: 5px;
		border: 1px solid rgb(170,197,192);
	}

	#container4 {
		float: left;
	}
	
	#form1 {
		width: 500px;
		height: 500px;
		border: 1px solid rgb(170,197,192);
		/*rxgb(170, 197, 192); darker
		rxgb(204,221,221) lighter */
	}
	
  </style>
</head>

<body>

<div id="root">
	<div id="customizer" style="display: none;">
		<div id="customizer-toolbar">
			<span id="customizer-label">Customizer: </span>
			<span class="customizer-button" id="customizer-done">Done</span> 
			<span class="customizer-button" id="customizer-cancel">Cancel</span>
			<span id="customizer-info">Info</span>
		</div>
		<div id="glasspane">
			<div id="glasspane-highlighter" style="display: none;">
				<div class="handle" style="position: absolute; top: 0px; left: 0px;"></div>
				<div class="handle" style="position: absolute; top: 0px; right: 0px;"></div>
				<div class="handle" style="position: absolute; bottom: 0px; left: 0px;"></div>
				<div class="handle" style="position: absolute; bottom: 0px; right: 0px;"></div>
			</div>
			<div id="glasspane-inline-editor" style="display: none;" >
				<div id="glasspane-actual-editor" >&nbsp;</div>
			</div>
		</div>
	</div>

	<div id="doc">
		<div class="container" id="container1">
			<span class="customizer-button" id="customize-button">Customize</span>
		</div>
		<div class="container" id="container2">
			<div class="component" id="tabs">
				<span class="tab">Home</span><span class="tab">Contacts</span><span class="tab">Calendar</span><span class="tab">Games</span>
			</div>
			<div class="component" id="tab-submenu">
				&nbsp;
			</div>
			<div class="component" id="spacer" style="height: 10px;"></div>
		</div>
		<div class="container" id="container3">
			<div class="component" id="menu1">
				<div class="titlebar">
					Quick Actions
				</div>
				<div class="menu-button">Add a Contact</div>
				<div class="menu-button">Make an Appointment</div>
				<div class="menu-button">Schedule a Meeting</div>
				<div class="menu-button">Take a Vacation</div>
			</div>
		</div>

		<div class="component" id="spacer2" style="float: left; width: 10px; height: 1px;"></div>

		<div class="container" id="container4">
			<div class="component" id="form1">
				<div class="titlebar">
					Contact Information
				</div>
			</div>
		</div>
	</div>
</div>

<!-- ------------------------------------------------------------------------------------------------- -->
<script type="text/javascript">
 // <![CDATA[
	Object.extend(String.prototype, {
		trim: function() {
			var str = this.replace(/^[\s]*/, "");
			return str.replace(/[\s]*$/, "");
		}
	});

	var Customizer = {
		customizer: dojo.byId("customizer"),
		customizerStyle: dojo.byId("customizer").style,
		customizerToolbar: dojo.byId("customizer-toolbar"),
		customizerToolbarStyle: dojo.byId("customizer-toolbar").style,
		glasspane: dojo.byId("glasspane"),
		glasspaneStyle: dojo.byId("glasspane").style,
		highlighter: dojo.byId("glasspane-highlighter"),
		highlighterStyle: dojo.byId("glasspane-highlighter").style,
		inlineEditorDiv: dojo.byId("glasspane-inline-editor"),
		inlineEditorDivStyle: dojo.byId("glasspane-inline-editor").style,
		inlineEditor: dojo.byId("glasspane-actual-editor"),
		richTextEditor: null,
		selectedElement: null,
		
		isInEdit: function() {
			return this.inlineEditorDivStyle.display == "block";
		},
		
		show: function() {
			// Have to display it to get the correct height.
			this.customizerStyle.display = "block";
			this.glasspaneStyle.top = this.customizerToolbar.offsetHeight + "px";
			this.customizerStyle.display = "none";
			this.inlineEditorDivStyle.display = "none";
			dojo.fx.wipeIn(this.customizer, 250);
		},
		
		hide: function() {
			dojo.fx.wipeOut(this.customizer, 250);
		},
		
		glasspaneOffset: function(pageX, pageY) {
			return [ pageX - this.glasspane.offsetLeft,
					 pageY - this.glasspane.offsetTop];
		},

		// Finds the deepest displayed element under the given element located at point x,y. Returns null if not found.
 		findElementAt: function(rootElement, pageX, pageY) {
 			for (i in rootElement.childNodes) {
 				var foundElement = this.findElementAt(rootElement.childNodes[i], pageX, pageY);
 				if (foundElement != null) {
 					return foundElement;
 				}
 			}
 			
			if (Position.within(rootElement, pageX, pageY)) {
	 			return rootElement;
	 		}
	 		
	 		return null;
 		},

		// Visually marks the selected item with the highlighter.
		markSelectedItem: function() {
			var pos = this.glasspaneOffset(this.selectedElement.offsetLeft, this.selectedElement.offsetTop);
			this.highlighterStyle.top = pos[1] + "px";
			this.highlighterStyle.left = pos[0] + "px";
			this.highlighterStyle.width = (this.selectedElement.offsetWidth - 2) + "px";
			this.highlighterStyle.height = (this.selectedElement.offsetHeight - 2) + "px";
			this.highlighterStyle.display = "block";
		},
		
		cleanupEditor: function() {
				// Because of an Editor bug, remove any toolbar from a previous edit.
				var node = this.inlineEditorDiv.firstChild;
				while (node != null) {
					var nextNode = node.nextSibling;
					if (node.className && node.className == "toolbarContainer") {
						dojo.dom.removeNode(node);
					}

					node = nextNode;
				}
				
				// Remove previous content
				dojo.dom.removeChildren(this.inlineEditor);
		},
		 		
 		startInlineEdit: function() {
			if (!this.isInEdit() && this.selectedElement != null && this.selectedElement.childNodes.length > 0) {
				// Edit text/properties
				//var child = this.selectedElement.childNodes[0];
				//if (child.nodeType == child.TEXT_NODE) {
					this.cleanupEditor();
					// This works but has some side-effects: 
					this.inlineEditor.appendChild(this.selectedElement.cloneNode(true));
					//this.inlineEditor.appendChild(child.cloneNode(true));
					
					//this.richTextEditor = dojo.widget.fromScript("Editor", { }, this.inlineEditor);
					this.richTextEditor = dojo.widget.fromScript("richtext", { }, this.inlineEditor);
					dojo.event.connect(this.richTextEditor, "onSave", this, "confirmInlineEdit");
					dojo.event.connect(this.richTextEditor, "onCancel", this, "cancelInlineEdit");

					var pos = this.glasspaneOffset(this.selectedElement.offsetLeft, this.selectedElement.offsetTop);
					this.inlineEditorDivStyle.top = (pos[1] + this.selectedElement.offsetHeight) + "px";
					this.inlineEditorDivStyle.left = pos[0] + "px";
					this.inlineEditorDivStyle.display = "block";
					var width = (this.selectedElement.offsetWidth - 2);
					this.inlineEditorDivStyle.width = "600px"; //width + "px";
					this.inlineEditorDivStyle.height = "200px";
				//}
			}
 		},
 		
 		confirmInlineEdit: function() {
			this.selectedElement.innerHTML = this.richTextEditor.getEditorContent();
			this.inlineEditorDivStyle.display = "none";
			cleanupEditor();
			// Remark the selected item, the size may have changed.
			this.markSelectedItem();
 		},

 		cancelInlineEdit: function() {
			this.inlineEditorDivStyle.display = "none";
			cleanupEditor();
 		},

		selectFromEvent: function(event) {
			if (this.isInEdit()) {
				return false;
			}
			
			var element = this.findElementAt(dojo.byId("doc"), event.pageX, event.pageY);
			this.selectedElement = element;
			dojo.byId("customizer-info").innerHTML = "x=" + event.pageX + " y=" + event.pageY + " element: " + (element ? ("&lt;" + element.tagName + " id=" + element.id + " class=" + element.className + "&gt;" ) : "");
			if (element == null) {
				this.highlighterStyle.display = "none";
				return;
			}

			this.markSelectedItem();
		}
	};

	Behaviour.register({
		'#customize-button' : function(element) {
			element.onclick = function(event) {
				Customizer.show();
				return false;
			}
		},
		
		'#customizer-done' : function(element) {
			element.onclick = function(event) {
				Customizer.hide();
				return false;
			}
		},

		'#customizer-cancel' : function(element) {
			element.onclick = function(event) {
				Customizer.hide();
				return false;
			}
		},
		
		'#glasspane' : function(element) {
			element.onmousemove = function(event) {
				return false;
			},
			
			element.onclick = function(event) {
				Customizer.selectFromEvent(event);
				return false;
			},

			element.ondblclick = function(event) {
				Customizer.selectFromEvent(event);
				Customizer.startInlineEdit();
				return false;
			}
		},
		
		'#glasspane-inline-edit-tf' : function(element) {
			element.onkeypress = function(event) {
				if (event.keyCode == Event.KEY_RETURN) {
					Customizer.confirmInlineEdit();
					return false;
				}

				if (event.keyCode == Event.KEY_ESC) {
					Customizer.cancelInlineEdit();
					return false;
				}
			}
		},
		
		'#glasspane-inline-edit-ok' : function(element) {
			element.onclick = function(event) {
				Customizer.confirmInlineEdit();
				return false;
			}
		},

		'#glasspane-inline-edit-cancel' : function(element) {
			element.onclick = function(event) {
				Customizer.cancelInlineEdit();
				return false;
			}
		},

	});

 // ]]>
 </script>

</body>
</html>
